<?php
// 应用公共文件
use think\facade\Cache;
use think\facade\Db;
use think\facade\Config;
use think\facade\Request;
use think\Http;

// 获取请求参数
if (!function_exists('get_params')) {
    function get_params() {
        return array_merge(Request::param(), Request::post(), Request::get());
    }
}

// 返回数据
if (!function_exists('to_assign')) {
    function to_assign($code = 0, $msg = '', $data = []) {
        $result = [
            'code' => $code,
            'msg'  => $msg,
            'data' => $data
        ];
        return json($result);
    }
}

// 返回表格数据
if (!function_exists('table_assign')) {
    function table_assign($code = 0, $msg = '', $data = []) {
        $result = [
            'code' => $code,
            'msg'  => $msg
        ];
        
        if (isset($data['total'])) {
            $result['count'] = $data['total'];
        } else if (isset($data['data']) && isset($data['total'])) {
            $result['data'] = $data['data'];
            $result['count'] = $data['total'];
        } else {
            $result['data'] = $data;
            $result['count'] = count($data);
        }
        
        return json($result);
    }
}

if (!function_exists('get_salt')) {
    /**
     * 生成随机字符串
     * @param int $len 长度
     * @return string
     */
    function get_salt($len = 6)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_[]{}<>~`+=,.;:/?|';
        $salt = '';
        for ($i = 0; $i < $len; $i++) {
            $salt .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $salt;
    }
}

if (!function_exists('generate_initial_password')) {
    /**
     * 生成用户初始密码（6位小写字母+数字）
     * @param int $len 长度
     * @return string
     */
    function generate_initial_password($len = 6)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
        $password = '';
        for ($i = 0; $i < $len; $i++) {
            $password .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $password;
    }
}   

//设置缓存
function set_cache($key='', $value='', $date = 86400)
{
    Cache::set($key, $value, $date);
}

//读取缓存
function get_cache($key)
{
    return Cache::get($key);
}

//清空缓存
function clear_cache($key)
{
    Cache::delete($key);
}

//读取文件配置
function get_config($key)
{
    return Config::get($key);
}

//读取系统配置
function get_system_config($name='', $key = '')
{
    try {
        $config = [];
        if (get_cache('system_config' . $name)) {
            $config = get_cache('system_config' . $name);
        } else {
            $conf = Db::name('config')->where('name', $name)->find();
            if (isset($conf['content'])) {
                // 增强反序列化错误处理
                $config = @unserialize($conf['content']);
                if ($config === false) {
                    $config = [];
                }
            }
            set_cache('system_config' . $name, $config);
        }
        if ($key == '') {
            // 确保返回数组
            return is_array($config) ? $config : [];
        } else {
            if (isset($config[$key])) {
                return $config[$key];
            }
            else{
                return '';
            }
        }
    } catch (\Exception $e) {
        // 返回默认值
        return $key == '' ? [] : '';
    }
}

//设置系统配置
function set_system_config($name='', $key='', $value='')
{
    try {
        $config = [];
        $conf = Db::name('config')->where('name', $name)->find();
        if ($conf && $conf['content']) {
            // 增强反序列化错误处理
            $config = @unserialize($conf['content']);
            if ($config === false) {
                $config = [];
            }
        }
        $config[$key] = $value;
        set_cache('system_config' . $name, $config);
        $content = serialize($config);
        Db::name('config')->where('name', $name)->update(['content'=>$content]);
    } catch (\Exception $e) {
        // 静默失败
    }
}

/**
 * 格式化字节大小
 * @param  int|float $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 */
function format_bytes($size, $delimiter = '')
{
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) {
        $size = $size / 1024;
    }
    return round($size, 2) . $delimiter . $units[$i];
}

//写入操作日志
function add_log($type, $param_id = '', $param = [] ,$subject='')
{
	$title = '操作';
	$type_action = get_config('log.type_action');
	if(isset($type_action[$type])){
		$title = $type_action[$type];
	}
	
	// 从请求头部获取JWT令牌
	$userId = 0;
	$authHeader = request()->header('Authorization');
	if ($authHeader) {
		$token = str_replace('Bearer ', '', $authHeader);
		// 使用JWT验证令牌
		try {
			$jwtConfig = get_config('jwt');
			if ($jwtConfig && isset($jwtConfig['key'])) {
				\Firebase\JWT\JWT::$leeway = 60; // 留60秒余地
				$decoded = \Firebase\JWT\JWT::decode($token, new \Firebase\JWT\Key($jwtConfig['key'], $jwtConfig['algorithm'] ?? 'HS256'));
				$decoded_array = json_decode(json_encode($decoded), true);
				
				// 兼容新的JWT格式（sub字段）和原系统格式（data.userid字段）
				if (isset($decoded_array['sub'])) {
					$userId = (int)$decoded_array['sub'];
				} elseif (isset($decoded_array['data']['userid'])) {
					$userId = (int)$decoded_array['data']['userid'];
				}
			}
		} catch (\Exception $e) {
			// 静默失败，继续处理
		}
	}
	
	/** @var \think\Http $http */
	$http = app('http');
	
	// 为$request变量添加类型提示，解决静态分析工具无法识别controller()方法的问题
	/** @var \think\Request $request */
	$request = app('request');
	
	$data = [
		'uid' => $userId,
		'type' => $type,
		'action' => $title,
		'param_id' => $param_id,
		'param' => json_encode($param),
		'module' => strtolower($http->getName()),
		'controller' => strtolower($request->controller()),
		'function' => strtolower($request->action()),
		'ip' => $request->ip(),
		'create_time' => time(),
		'subject' => '系统'
	];
	if($subject!=''){
		$data['subject'] = $subject;
	}
	else{
		$rule = $data['module'] . '/' . $data['controller'] . '/' . $data['function'];
		$rule_menu = Db::name('AdminRule')->where(array('mig_src' => $rule))->find();
		if($rule_menu){
			$data['subject'] = $rule_menu['name'];
		}
	}
	Db::name('AdminLog')->strict(false)->field(true)->insert($data);
}

// YAML解析函数兼容性处理
if (!function_exists('yaml_parse_file')) {
    /**
     * YAML文件解析函数
     * 当系统没有安装PHP YAML扩展时提供基础的YAML解析功能
     * @param string $filename YAML文件路径
     * @return array|false
     */
    function yaml_parse_file(string $filename) {
        if (!is_file($filename)) {
            return false;
        }
        
        // 尝试使用YamlHelper类
        if (class_exists('\app\common\YamlHelper')) {
            try {
                return \app\common\YamlHelper::parseFile($filename);
            } catch (\Exception $e) {
                return false;
            }
        }
        
        return [];
    }
}